package test;

/**
 * Created by MtRider on 2021/11/1 21:25
 */
public class Calcsizeof {
    private static Runtime rTime = Runtime.getRuntime();

    private static long usedMemory() {
        return rTime.totalMemory() - rTime.freeMemory();
    }

    private static void runGC() {
        for (int i = 0; i < 4; i++) {
            long usedMem1 = usedMemory();
            long usedMem2 = Long.MAX_VALUE;

            for (int j = 0; (usedMem1 < usedMem2) && (j < 500); j++) {
                rTime.runFinalization();
                rTime.gc();
                Thread.yield();

                usedMem2 = usedMem1;
                usedMem1 = usedMemory();
            }
        }
    }

    private void calcSize() {
        runGC();
        long heap1 = 0;
        final int count = 100000;
        Object[] objs = new Object[count];

        for (int i = -1; i < count; i++) {
            Object obj = null;
            //Object所占的内存空间(8个字节)+最大基本类型(long)所占内存（8个字节）=16
            //obj = new Object(); // Object size = 8 // ? 16
             //obj = new Integer(i); // Object size = 16 // ? 16
           //obj = new Short((short)i); // Object size = 16 // ? 16
            // obj = new Long(i); // Object size = 16 // ? 24
            // obj = new Byte((byte)0); // Object size = 16 // ? 16
            // obj = new Character((char)i); // Object size = 16 // ? 16
            // obj = new Float(i); // Object size = 16 // ? 16
            // obj = new Double(i); // Object size = 16 // ? 24
            // obj = new Boolean(false); // Object size = 16 // ? 16
            // obj = new String(); // Object size = 40 // ? 24

            if (i < 0) {
                obj = null;
                runGC();
                heap1 = usedMemory();
            } else {
                objs[i] = obj;
            }
        }

        runGC();
        long heap2 = usedMemory();
        final int size = (int)Math.round((heap2 - heap1)/(double)count);
        System.out.println("heap1 = " + heap1 + "; heap2 = " + heap2);
        System.out.println("heap2 - heap1 = " + (heap2 - heap1) + "; " + objs[0].getClass().getSimpleName() + " size = " + size);

        for (int i = 0; i < count; i++) {
            objs[i] = null;
        }
        objs = null;
        runGC();
    }

    public static void main(String[] args) {
        Calcsizeof calcsizeof = new Calcsizeof();
        calcsizeof.calcSize();
    }
}
